/**
 * 
 */
package de.cbf.cam.dsa.battle.ui.composites;

import java.util.List;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseMoveListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Widget;

import de.cbf.cam.dsa.battle.ui.dialogs.DKChooseDialog;
import de.cbf.cam.dsa.model.entities.BattleChar;
import de.cbf.cam.dsa.model.entities.FightPosition;
import de.cbf.cam.dsa.model.entities.weapon.WeaponMelee;
import de.cbf.cam.dsa.model.util.Position3f;

/**
 * @author Nebelritter
 *
 */
public class CompositeChooseEnemys extends Composite {
	/**
	 * @uml.property  name="attackerInfo"
	 * @uml.associationEnd  multiplicity="(1 1)"
	 */
	private CompositeNPCDisplay attackerInfo;
	/**
	 * @uml.property  name="enemyInfo"
	 * @uml.associationEnd  multiplicity="(1 1)"
	 */
	private CompositeNPCDisplay enemyInfo; //  @jve:decl-index=0:visual-constraint="19,7"
	
	/**
	 * @uml.property  name="buttonOK"
	 * @uml.associationEnd  multiplicity="(1 1)"
	 */
	private Button buttonOK;
	/**
	 * @uml.property  name="buttonCancel"
	 * @uml.associationEnd  multiplicity="(1 1)"
	 */
	private Button buttonCancel;
	
	/**
	 * @uml.property  name="tableEnemys"
	 * @uml.associationEnd  multiplicity="(1 1)"
	 */
	private Table tableEnemys;
	/**
	 * @uml.property  name="tableOthers"
	 * @uml.associationEnd  multiplicity="(1 1)"
	 */
	private Table tableOthers;
	
	/**
	 * @uml.property  name="hoverListener"
	 * @uml.associationEnd  multiplicity="(1 1)"
	 */
	private MouseMoveListener hoverListener = new HoverListener();
	
	/**
	 * @uml.property  name="character"
	 * @uml.associationEnd  
	 */
	private BattleChar character;
		
//========================
//		constructors
//========================
	/**
	 * @param parent
	 * @param style
	 */
	public CompositeChooseEnemys(Composite parent, int style) {
		super(parent, style);
		
		GridLayout layout = new GridLayout(2,false);
		layout.marginHeight = 0;
		layout.marginWidth = 0;		
		setLayout(layout);
		
		GridData infoLayoutData = new GridData(SWT.FILL,SWT.CENTER,true,false,1,1);
		attackerInfo = new CompositeNPCDisplay(this,infoLayoutData);
		
		Group grpAll = new Group(this, SWT.NORMAL);
		grpAll.setLayoutData(new GridData(SWT.FILL,SWT.FILL,true,true,1,30));
		grpAll.setLayout(new GridLayout(1,false));
		grpAll.setText("Alle");
				
			tableOthers = new Table(grpAll, SWT.BORDER|SWT.H_SCROLL|SWT.V_SCROLL|SWT.MULTI|SWT.FULL_SELECTION);
			tableOthers.setLayoutData(new GridData(SWT.FILL,SWT.FILL,true,true,1,1));
			tableOthers.setHeaderVisible(true);
			tableOthers.setLinesVisible(true);
			tableOthers.addSelectionListener(new SelectEnemy());
			tableOthers.addMouseMoveListener(hoverListener);	
			
				TableColumn column = new TableColumn(tableOthers, SWT.LEFT);
				column.setText("Name");
				column.setWidth(100);
			
				column = new TableColumn(tableOthers, SWT.LEFT);
				column.setText("Status");
				column.setWidth(180);
				
				column = new TableColumn(tableOthers, SWT.CENTER);
				column.setText("Entfernung");
				column.setWidth(80);
				
		Group grpEnemys = new Group(this, SWT.NORMAL);
		grpEnemys.setLayoutData(new GridData(SWT.FILL,SWT.FILL,true,true,1,30));
		grpEnemys.setLayout(new GridLayout(1,false));
		grpEnemys.setText("Gegner");
		
			tableEnemys = new Table(grpEnemys, SWT.BORDER|SWT.H_SCROLL|SWT.V_SCROLL|SWT.SINGLE|SWT.FULL_SELECTION);
			tableEnemys.setLayoutData(new GridData(SWT.FILL,SWT.FILL,true,true,1,1));
			tableEnemys.setHeaderVisible(true);
			tableEnemys.setLinesVisible(true);
			tableEnemys.addSelectionListener(new RemoveEnemy());
			tableEnemys.addMouseMoveListener(hoverListener);	
			
				column = new TableColumn(tableEnemys, SWT.LEFT);
				column.setText("Name");
				column.setWidth(100);
			
				column = new TableColumn(tableEnemys, SWT.LEFT);
				column.setText("Status");
				column.setWidth(180);
			
		enemyInfo = new CompositeNPCDisplay(this,infoLayoutData);
		
		Composite compositeButtons = new Composite(this, SWT.NONE);
		compositeButtons.setLayoutData(new GridData(SWT.FILL,SWT.CENTER,true,false,2,1));
		compositeButtons.setLayout(new GridLayout(2,false));
		
			buttonCancel = new Button(compositeButtons, SWT.PUSH);
			buttonCancel.setLayoutData(new GridData(SWT.RIGHT,SWT.CENTER,true,false,1,1));
			buttonCancel.setText("Abbrechen");
			buttonCancel.addSelectionListener(new ButtonCancelListener());
		
			buttonOK = new Button(compositeButtons, SWT.PUSH);
			buttonOK.setLayoutData(new GridData(SWT.RIGHT,SWT.CENTER,false,false,1,1));
			buttonOK.setText("OK");
			buttonOK.addSelectionListener(new ButtonOKListener());
			
	}
//========================
//	   public methods
//========================	

//========================
//    standard methods
//========================

//========================
// 	   private methods
//========================
private void fillTables(List<BattleChar> others,List<BattleChar> enemys){
	tableEnemys.removeAll();
	for(int i =0;i<enemys.size();i++){
		TableItem item = new TableItem(tableEnemys, SWT.NORMAL);
		BattleChar enemy = enemys.get(i);
		item.setText(0,enemy.getName());
		item.setText(1,enemy.getWoundsDescription());
		
		item.setData(enemy);			
	}	
	
	tableOthers.removeAll();
	if(character!=null)
	for(int i =0;i<others.size();i++){
		TableItem item = new TableItem(tableOthers, SWT.NORMAL);
		BattleChar other = others.get(i);
		item.setText(0,other.getName());
		item.setText(1,other.getWoundsDescription());
		item.setText(2,other.getPosition().lenght()+"");
		if(enemys.contains(other)){
			tableOthers.select(i);
		}
		item.setData(other);			
	}	
}
//========================
// 	SHORT property access
//========================

//========================
//		getters
//========================
	
//========================
//		setters
//========================
	public void setData(BattleChar character,List<BattleChar> others) {
		this.character =character;
		attackerInfo.setCharacter(character);		
		fillTables(others,character.getEnemysNames());		
	}
//========================
//		listeners
//========================
	/**
	 * @author  Surfer
	 */
	private class HoverListener implements MouseMoveListener{
		/**
		 * @uml.property  name="lastCharacter"
		 * @uml.associationEnd  
		 */
		private BattleChar lastCharacter=null; 
		@Override
		public void mouseMove(MouseEvent e) {
			Widget widget =e.widget;
			if (widget instanceof Table) {
				Table table = (Table) widget;
				TableItem item = table.getItem(new Point(e.x,e.y));
				BattleChar character=null;
				if(item!=null){
					character = (BattleChar)item.getData();
					if(!character.equals(lastCharacter)){
						enemyInfo.setCharacter(character);
//						table.setSelection(item);
						lastCharacter = character;
					}					
				}else{
					if(lastCharacter!=null){

						lastCharacter=null;
					}					
				}
			}			
		}		
	}
	
	private class SelectEnemy extends SelectionAdapter{
		@Override
		public void widgetSelected(SelectionEvent e) {
			tableEnemys.removeAll();
			TableItem [] itemsSelected=tableOthers.getSelection();
			for(int i=0;i<itemsSelected.length;i++){
				TableItem item = new TableItem(tableEnemys, SWT.NORMAL);
				BattleChar other = (BattleChar)itemsSelected[i].getData();
				item.setText(0,other.getName());
				item.setText(1,other.getWoundsDescription());
				
				item.setData(other);				
			}			
		}		
	}
	private class RemoveEnemy extends SelectionAdapter{
		@Override
		public void widgetSelected(SelectionEvent e) {
			int index = tableEnemys.getSelectionIndex();
			tableEnemys.remove(index);		
		}		
	}
	/**
	 * @author Nebelritter
	 *
	 */
	private class ButtonOKListener extends SelectionAdapter{
		@Override
		public void widgetSelected(SelectionEvent e) {
			TableItem[] items = tableEnemys.getItems();
			character.removeAllEnemys();
			for(int i=0;i<items.length;i++){
				BattleChar enemy = (BattleChar)items[i].getData();
				//calculate distance
				Position3f vectorDistance = character.getPosition().substract(enemy.getPosition());
				float distance =vectorDistance.lenght();
				//add as enemy to both (with same distance)
				String dk = findDK(distance,enemy);
				FightPosition fightPosition = new FightPosition(distance,dk);
				character.addEnemy(enemy,fightPosition);
				enemy.addEnemy(character, fightPosition);
			}
			CompositeChooseEnemys.this.dispose();
		}

		/**
		 * method to find the DK
		 * 
		 * @returns <li> according Letter for DK
		 * 			<li> null if distance is to big for hand to hand 	
		 */
		private String findDK(Float distance, BattleChar enemy) {
			//find longest weapon
			Float longestWeaponRange;
			Float characterRange = character.getCharacter().findLongestWeaponRange();
			Float enemysRange = enemy.getCharacter().findLongestWeaponRange();
			if(characterRange > enemysRange){
				longestWeaponRange = characterRange;
			}else{
				longestWeaponRange = enemysRange;
			}
			// distance< range of longest weapon -> check if DK can be chosen  by ini
			if(distance<longestWeaponRange){
				//check ini difference
				int iniDiff = character.findINIDifference(enemy);
				if(Math.abs(iniDiff)>=4){
					return openDKChangeDialog(character, enemy,longestWeaponRange);
				}else{
					//no change of DK possible, take highest
					if(longestWeaponRange <= WeaponMelee.HANDGEMENGE)return "H";
					if(longestWeaponRange <= WeaponMelee.NAHKAMPF)return "N";
					if(longestWeaponRange <= WeaponMelee.STANGENWAFFE)return "S";
					if(longestWeaponRange <= WeaponMelee.PIKE) return "P";
				}
			}
			return "-";
		}		
		
		
		private String openDKChangeDialog(BattleChar character,BattleChar enemy,
				Float longestWeapon){				
			DKChooseDialog dialog = new DKChooseDialog(getShell());
			dialog.create();
			dialog.setData(character,enemy,longestWeapon);
			String text = dialog.openForResult();
			return text;
		}
	}
	private class ButtonCancelListener extends SelectionAdapter{
		@Override
		public void widgetSelected(SelectionEvent e) {
			CompositeChooseEnemys.this.dispose();
		}		
	}
}
